package lol.clann.bukkit.pluginboot.model.logger;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.slf4j.Marker;
import org.slf4j.event.Level;

/**
 * @author pyz
 * @date 2018/9/8 上午10:28
 */
public class Logger implements org.slf4j.Logger {

    private String name;

    private boolean trace = false;
    private boolean debug = false;
    private boolean info = true;
    private boolean warn = true;
    private boolean error = true;

    private Logger(String name) {
        this.name = name;
    }

    public static org.slf4j.Logger getLogger(String name) {
        return new Logger(name);
    }

    public void setTrace(boolean trace) {
        this.trace = trace;
    }

    public void setDebug(boolean debug) {
        this.debug = debug;
    }

    public void setInfo(boolean info) {
        this.info = info;
    }

    public void setWarn(boolean warn) {
        this.warn = warn;
    }

    public void setError(boolean error) {
        this.error = error;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public boolean isTraceEnabled() {
        return trace;
    }

    @Override
    public void trace(String s) {
        log(trace, Level.TRACE, ChatColor.GRAY, s, null, null);
    }

    @Override
    public void trace(String s, Object o) {
        log(trace, Level.TRACE, ChatColor.GRAY, s, null, o);
    }

    @Override
    public void trace(String s, Object o, Object o1) {
        log(trace, Level.TRACE, ChatColor.GRAY, s, null, o, o1);
    }

    @Override
    public void trace(String s, Object... objects) {
        log(trace, Level.TRACE, ChatColor.GRAY, s, null, objects);
    }

    @Override
    public void trace(String s, Throwable throwable) {
        log(trace, Level.TRACE, ChatColor.GRAY, s, throwable, null);
    }

    @Override
    public boolean isTraceEnabled(Marker marker) {
        return false;
    }

    @Override
    public void trace(Marker marker, String s) {

    }

    @Override
    public void trace(Marker marker, String s, Object o) {

    }

    @Override
    public void trace(Marker marker, String s, Object o, Object o1) {

    }

    @Override
    public void trace(Marker marker, String s, Object... objects) {

    }

    @Override
    public void trace(Marker marker, String s, Throwable throwable) {

    }

    @Override
    public boolean isDebugEnabled() {
        return debug;
    }

    @Override
    public void debug(String s) {
        log(debug, Level.DEBUG, ChatColor.BLUE, s, null, null);
    }

    @Override
    public void debug(String s, Object o) {
        log(debug, Level.DEBUG, ChatColor.BLUE, s, null, o);
    }

    @Override
    public void debug(String s, Object o, Object o1) {
        log(debug, Level.DEBUG, ChatColor.BLUE, s, null, o, o1);
    }

    @Override
    public void debug(String s, Object... objects) {
        log(debug, Level.DEBUG, ChatColor.BLUE, s, null, objects);
    }

    @Override
    public void debug(String s, Throwable throwable) {
        log(debug, Level.DEBUG, ChatColor.BLUE, s, throwable, null);
    }

    @Override
    public boolean isDebugEnabled(Marker marker) {
        return false;
    }

    @Override
    public void debug(Marker marker, String s) {

    }

    @Override
    public void debug(Marker marker, String s, Object o) {

    }

    @Override
    public void debug(Marker marker, String s, Object o, Object o1) {

    }

    @Override
    public void debug(Marker marker, String s, Object... objects) {

    }

    @Override
    public void debug(Marker marker, String s, Throwable throwable) {

    }

    @Override
    public boolean isInfoEnabled() {
        return info;
    }

    @Override
    public void info(String s) {
        log(info, Level.INFO, ChatColor.GREEN, s, null, null);
    }

    @Override
    public void info(String s, Object o) {
        log(info, Level.INFO, ChatColor.GREEN, s, null, o);
    }

    @Override
    public void info(String s, Object o, Object o1) {
        log(info, Level.INFO, ChatColor.GREEN, s, null, o, o1);
    }

    @Override
    public void info(String s, Object... objects) {
        log(info, Level.INFO, ChatColor.GREEN, s, null, objects);
    }

    @Override
    public void info(String s, Throwable throwable) {
        log(info, Level.INFO, ChatColor.GREEN, s, throwable, null);
    }

    @Override
    public boolean isInfoEnabled(Marker marker) {
        return false;
    }

    @Override
    public void info(Marker marker, String s) {
    }

    @Override
    public void info(Marker marker, String s, Object o) {
    }

    @Override
    public void info(Marker marker, String s, Object o, Object o1) {
    }

    @Override
    public void info(Marker marker, String s, Object... objects) {
    }

    @Override
    public void info(Marker marker, String s, Throwable throwable) {
    }

    @Override
    public boolean isWarnEnabled() {
        return warn;
    }

    @Override
    public void warn(String s) {
        log(warn, Level.WARN, ChatColor.GOLD, s, null);
    }

    @Override
    public void warn(String s, Object o) {
        log(warn, Level.WARN, ChatColor.GOLD, s, null, o);
    }

    @Override
    public void warn(String s, Object o, Object o1) {
        log(warn, Level.WARN, ChatColor.GOLD, s, null, o, o1);
    }

    @Override
    public void warn(String s, Object... objects) {
        log(warn, Level.WARN, ChatColor.GOLD, s, null, objects);
    }

    @Override
    public void warn(String s, Throwable throwable) {
        log(warn, Level.WARN, ChatColor.GOLD, s, throwable, null);
    }

    @Override
    public boolean isWarnEnabled(Marker marker) {
        return false;
    }

    @Override
    public void warn(Marker marker, String s) {
    }

    @Override
    public void warn(Marker marker, String s, Object o) {
    }

    @Override
    public void warn(Marker marker, String s, Object o, Object o1) {
    }

    @Override
    public void warn(Marker marker, String s, Object... objects) {
    }

    @Override
    public void warn(Marker marker, String s, Throwable throwable) {
    }

    @Override
    public boolean isErrorEnabled() {
        return error;
    }

    @Override
    public void error(String s) {
        log(error, Level.ERROR, ChatColor.RED, s, null, null);
    }

    @Override
    public void error(String s, Object o) {
        log(error, Level.ERROR, ChatColor.RED, s, null, o);
    }

    @Override
    public void error(String s, Object o, Object o1) {
        log(error, Level.ERROR, ChatColor.RED, s, null, o, o1);
    }

    @Override
    public void error(String s, Object... objects) {
        log(error, Level.ERROR, ChatColor.RED, s, null, objects);
    }

    @Override
    public void error(String s, Throwable throwable) {
        log(error, Level.ERROR, ChatColor.RED, s, throwable, null);
    }

    @Override
    public boolean isErrorEnabled(Marker marker) {
        return false;
    }

    @Override
    public void error(Marker marker, String s) {
    }

    @Override
    public void error(Marker marker, String s, Object o) {
    }

    @Override
    public void error(Marker marker, String s, Object o, Object o1) {
    }

    @Override
    public void error(Marker marker, String s, Object... objects) {
    }

    @Override
    public void error(Marker marker, String s, Throwable throwable) {
    }

    protected void log(boolean log, Level level, ChatColor color, String message, Throwable e, Object... params) {
        if (!log) {
            return;
        }
        Bukkit.getConsoleSender().sendMessage(format(level, color, message, params));
        if (e != null) {
            e.printStackTrace();
        }
    }

    protected String format(Level level, ChatColor color, String message, Object... params) {
        StringBuilder sb = new StringBuilder();
        sb.append("[").append(level.name()).append("]");
        sb.append("[").append(name).append("]");
        sb.append(getPrefix());
        if (color != null) {
            sb.append(color.toString());
        }
        if (message == null || params == null || params.length == 0) {
            return message == null ? sb.toString() : sb.append(message).toString();
        }
        String[] ss = message.split("\\{\\}");
        for (int i = 0; i < ss.length; i++) {
            sb.append(ss[i]);
            if (i < params.length) {
                sb.append(String.valueOf(params[i]));
            } else {
                sb.append("{}");
            }
        }
        return sb.toString();
    }

    private String getPrefix() {
        StackTraceElement stackTrace = Thread.currentThread().getStackTrace()[5];
        return "[" + stackTrace.getFileName() + " " + stackTrace.getLineNumber() + "]";
    }

}
